﻿
using System;

namespace Patterns4Net.PatternEnforcer.Cmd.Output
{
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using Core;
    using Attributes;


    /// <summary>
    /// Provides a strategy to output <see cref="PatternEnforcer"/> result 
    /// in an xml format which conforms to the output.xsd XML Schema.
    /// </summary>
    public class XmlOutput : IOutputFormatter
    {
        private XmlTextWriter xmlWriter;

        public void Start(TextWriter writer)
        {
            this.xmlWriter = new XmlTextWriter(writer);
            xmlWriter.Formatting = Formatting.Indented;
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("enforcer-results");
        }

        public void Print(IEnumerable<PatternEnforcer.ResultItem> result, TextWriter writer)
        {
            foreach (var resultItem in result)
            {
                xmlWriter.WriteStartElement("element");

                xmlWriter.WriteStartElement("code-element");
                xmlWriter.WriteAttributeString("name", resultItem.Member.FullName);
                if (resultItem.Member.DeclaringType != null)
                {
                    xmlWriter.WriteAttributeString("declaring-type", resultItem.Member.DeclaringType.FullName);
                }

                xmlWriter.WriteEndElement();    // end of: code-element

                xmlWriter.WriteStartElement("errors");
                foreach (var checkerResult in resultItem.CheckerResults)
                {
                    Print(checkerResult, xmlWriter);
                }
                xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();    // end of: "element"
            }
        }

        public void End(TextWriter writer)
        {
            xmlWriter.WriteEndElement();
            xmlWriter.Flush();
            xmlWriter.Close();
        }

        private static void Print(KeyValuePair<IPattern, CheckerResult> checkerResult, XmlTextWriter xmlWriter)
        {
            xmlWriter.WriteStartElement("pattern");
            xmlWriter.WriteAttributeString("name", checkerResult.Key.Name);
            foreach (var error in checkerResult.Value.Errors)
            {
                xmlWriter.WriteStartElement("error");
                xmlWriter.WriteString(error.Message);
                xmlWriter.WriteEndElement();
            }
        }
    }
}
